package com.pig4cloud.pigx.contract.executer.position.multiple_changer;

import com.pig4cloud.pigx.common.customize.exception.MqAckException;
import com.pig4cloud.pigx.common.customize.mysql.utils.MysqlUtil;
import com.pig4cloud.pigx.common.customize.utils.CommonUtil;
import com.pig4cloud.pigx.common.seata.utils.SeataUtils;
import com.pig4cloud.pigx.contract.bo.ContractPositionMultipleChangeBO;
import com.pig4cloud.pigx.contract.constant.OrderExecutorErrorMsg;
import com.pig4cloud.pigx.contract.dto.AppContractMultipleChangeDTO;
import io.seata.common.util.CollectionUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * 仓位杠杆调整器
 *
 * @since 2022/8/17 11:12
 */
@Data
@Slf4j
@Component
public class PositionMultipleChangerManager {

	/**
	 * 仓位杠杆调整器
	 */
	private final List<PositionMultipleChanger> multipleHandlerList = new ArrayList<>();
	private final CommonUtil commonUtil;
	private final MysqlUtil mysqlUtil;

	/**
	 * 仓位杠杆调整
	 * <p>最多修改用户该币对下的两个仓位，目前不存在死锁的可能
	 *
	 * @param dto dto
	 * @since 2022/8/17 11:15
	 */
	public void change(AppContractMultipleChangeDTO dto) {
		ContractPositionMultipleChangeBO bo = new ContractPositionMultipleChangeBO();
		bo.setDto(dto);

		// 开启本地事务
		mysqlUtil.startLocalTx();
		for (PositionMultipleChanger i : multipleHandlerList) {
			try {
				if (CollectionUtils.isEmpty(bo.getList())) {
					i.getPosition(bo);
				}

				if (!i.support(bo)) {
					continue;
				}

				i.change(bo);
				i.success(bo);
				return;
			} catch (Exception e) {
				// 回滚全局事务（全仓）
				SeataUtils.rollbackGlobalTx();
				// 回滚本地事务
				mysqlUtil.rollbackLocalTx();

				i.fail(bo, e);
				log.error(OrderExecutorErrorMsg.POSITION_MULTIPLE_HANDLE_ERROR, e.getMessage());

				if (e instanceof MqAckException) {
					return;
				}
				throw e;
			}
		}

		throw new RuntimeException(OrderExecutorErrorMsg.POSITION_MULTIPLE_HANDLER_NOT_MATCH);
	}
}
